#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "web_server.h"
#include "http_server_impl.h"
#include <regex>

using namespace El::WebServer;

class ProxyRulesTest : public ::testing::Test {
protected:
    void SetUp() override {
        server_ = &HttpServerImpl::GetInstance();
    }

    void TearDown() override {
        server_->Stop();
        // 清理所有测试规则
        server_->RemoveProxyRule("/test/.*");
        server_->RemoveProxyRule("/api/v[0-9]+/.*");
        server_->RemoveProxyRule("/static/.*");
        server_->RemoveProxyRule("/auth/.*");
    }

    HttpServerImpl* server_;
};

// 测试简单的代理规则匹配
TEST_F(ProxyRulesTest, SimplePatternMatching) {
    std::vector<ProxyTarget> targets = {
        ProxyTarget("127.0.0.1", 8080)
    };
    
    // 注册简单模式
    EXPECT_TRUE(server_->RegisterProxyRule("/test/.*", targets));
    
    // 测试模式匹配
    std::regex pattern("/test/.*");
    EXPECT_TRUE(std::regex_match("/test/", pattern));
    EXPECT_TRUE(std::regex_match("/test/api", pattern));
    EXPECT_TRUE(std::regex_match("/test/api/users", pattern));
    EXPECT_FALSE(std::regex_match("/other/api", pattern));
}

// 测试复杂的正则表达式模式
TEST_F(ProxyRulesTest, ComplexPatternMatching) {
    std::vector<ProxyTarget> targets = {
        ProxyTarget("127.0.0.1", 8080)
    };
    
    // 注册版本化API模式
    EXPECT_TRUE(server_->RegisterProxyRule("/api/v[0-9]+/.*", targets));
    
    // 测试版本化API模式匹配
    std::regex pattern("/api/v[0-9]+/.*");
    EXPECT_TRUE(std::regex_match("/api/v1/users", pattern));
    EXPECT_TRUE(std::regex_match("/api/v2/orders", pattern));
    EXPECT_TRUE(std::regex_match("/api/v10/products", pattern));
    EXPECT_FALSE(std::regex_match("/api/users", pattern));
    EXPECT_FALSE(std::regex_match("/api/vx/users", pattern));
}

// 测试静态文件代理规则
TEST_F(ProxyRulesTest, StaticFileProxyRule) {
    std::vector<ProxyTarget> targets = {
        ProxyTarget("cdn.example.com", 443, true)
    };
    
    ProxyOptions options;
    options.preserve_host = false;
    options.strip_prefix = "/static";
    options.add_prefix = "/assets";
    
    EXPECT_TRUE(server_->RegisterProxyRule("/static/.*", targets, options));
}

// 测试认证服务代理规则
TEST_F(ProxyRulesTest, AuthServiceProxyRule) {
    std::vector<ProxyTarget> targets = {
        ProxyTarget("auth-service", 8443, true)
    };
    
    ProxyOptions options;
    options.timeout_ms = 10000; // 认证服务需要更长超时
    options.retry_count = 1;    // 认证失败不重试
    options.headers["X-Service-Name"] = "web-server";
    
    EXPECT_TRUE(server_->RegisterProxyRule("/auth/.*", targets, options));
}

// 测试代理规则的正则表达式编译
TEST_F(ProxyRulesTest, RegexCompilation) {
    std::vector<ProxyTarget> targets = {
        ProxyTarget("127.0.0.1", 8080)
    };
    
    // 测试有效的正则表达式
    EXPECT_TRUE(server_->RegisterProxyRule("/api/.*", targets));
    EXPECT_TRUE(server_->RegisterProxyRule("/users/[0-9]+", targets));
    
    // 注意：这里我们无法直接测试无效正则表达式，因为HttpServerImpl内部处理
    // 但我们可以测试一些边界情况
    EXPECT_TRUE(server_->RegisterProxyRule("/.*", targets)); // 匹配所有
    EXPECT_TRUE(server_->RegisterProxyRule("/specific/path", targets)); // 精确匹配
}

// 测试代理目标选择逻辑
TEST_F(ProxyRulesTest, TargetSelection) {
    // 多个目标的负载均衡配置
    std::vector<ProxyTarget> targets = {
        ProxyTarget("server1.local", 8080, false, 3, true),  // 权重3
        ProxyTarget("server2.local", 8080, false, 2, true),  // 权重2
        ProxyTarget("server3.local", 8080, false, 1, true),  // 权重1
        ProxyTarget("server4.local", 8080, false, 1, false)  // 禁用
    };
    
    ProxyOptions options;
    options.timeout_ms = 5000;
    
    EXPECT_TRUE(server_->RegisterProxyRule("/balanced/.*", targets, options));
}

// 测试代理规则冲突处理
TEST_F(ProxyRulesTest, RuleConflictHandling) {
    std::vector<ProxyTarget> targets1 = {
        ProxyTarget("server1.local", 8080)
    };
    
    std::vector<ProxyTarget> targets2 = {
        ProxyTarget("server2.local", 8080)
    };
    
    // 第一次注册应该成功
    EXPECT_TRUE(server_->RegisterProxyRule("/conflict/.*", targets1));
    
    // 重复注册相同模式应该失败
    EXPECT_FALSE(server_->RegisterProxyRule("/conflict/.*", targets2));
    
    // 移除后重新注册应该成功
    EXPECT_TRUE(server_->RemoveProxyRule("/conflict/.*"));
    EXPECT_TRUE(server_->RegisterProxyRule("/conflict/.*", targets2));
}

// 测试URL重写功能
TEST_F(ProxyRulesTest, URLRewriting) {
    std::vector<ProxyTarget> targets = {
        ProxyTarget("backend.local", 8080)
    };
    
    // 测试前缀移除和添加
    ProxyOptions options1;
    options1.strip_prefix = "/api/v1";
    options1.add_prefix = "/internal/v2";
    
    EXPECT_TRUE(server_->RegisterProxyRule("/rewrite1/.*", targets, options1));
    
    // 测试只移除前缀
    ProxyOptions options2;
    options2.strip_prefix = "/old-api";
    
    EXPECT_TRUE(server_->RegisterProxyRule("/rewrite2/.*", targets, options2));
    
    // 测试只添加前缀
    ProxyOptions options3;
    options3.add_prefix = "/new-prefix";
    
    EXPECT_TRUE(server_->RegisterProxyRule("/rewrite3/.*", targets, options3));
}

// 测试代理请求头处理
TEST_F(ProxyRulesTest, RequestHeaderHandling) {
    std::vector<ProxyTarget> targets = {
        ProxyTarget("api.backend.com", 443, true)
    };
    
    ProxyOptions options;
    options.preserve_host = true;
    options.headers["X-Forwarded-Proto"] = "https";
    options.headers["X-Forwarded-For"] = "client-ip";
    options.headers["Authorization"] = "Bearer secret-token";
    options.headers["User-Agent"] = "WebServer-Proxy/1.0";
    
    EXPECT_TRUE(server_->RegisterProxyRule("/headers/.*", targets, options));
}

// 测试超时和重试配置
TEST_F(ProxyRulesTest, TimeoutAndRetryConfiguration) {
    std::vector<ProxyTarget> targets = {
        ProxyTarget("slow-service.local", 8080)
    };
    
    // 高超时，低重试的配置
    ProxyOptions options1;
    options1.timeout_ms = 30000; // 30秒
    options1.retry_count = 1;    // 只重试1次
    
    EXPECT_TRUE(server_->RegisterProxyRule("/slow/.*", targets, options1));
    
    // 低超时，高重试的配置
    ProxyOptions options2;
    options2.timeout_ms = 1000;  // 1秒
    options2.retry_count = 5;    // 重试5次
    
    EXPECT_TRUE(server_->RegisterProxyRule("/fast/.*", targets, options2));
}

// 测试HTTPS目标配置
TEST_F(ProxyRulesTest, HTTPSTargetConfiguration) {
    // HTTPS目标
    std::vector<ProxyTarget> https_targets = {
        ProxyTarget("secure-api.com", 443, true),
        ProxyTarget("backup-secure.com", 8443, true)
    };
    
    ProxyOptions options;
    options.preserve_host = false; // 不保留原始host头
    
    EXPECT_TRUE(server_->RegisterProxyRule("/secure/.*", https_targets, options));
}

// 测试混合协议目标
TEST_F(ProxyRulesTest, MixedProtocolTargets) {
    std::vector<ProxyTarget> mixed_targets = {
        ProxyTarget("http-server.local", 8080, false),   // HTTP
        ProxyTarget("https-server.local", 8443, true),   // HTTPS
        ProxyTarget("another-http.local", 9000, false)   // HTTP
    };
    
    EXPECT_TRUE(server_->RegisterProxyRule("/mixed/.*", mixed_targets));
}